/*
桌上计算器
文法，拓广方法的编号是0： 
E' E
E E + T
E E - T
E T
T T * U
T T / U
T U
U + U
U - U
U X
X F ^ X
X F
F ( E )
F n
非终结符替换：
E 0
T 1
U 2
X 3
F 4
输入以EOF结束
分析表由
https://gitee.com/compilation-principle_2/generate-lr-analysis-table/blob/master/entry.cpp
的 saveLrTbl 函数生成，然后执行替换。 
*/ 
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <unordered_map>
#include <vector>
#include <stdexcept>
using namespace std;
#define NUM 'n'

struct Token {
	int tag;
	double val;
};

int scan(Token& tok) {
	char ch;
	int cnt=scanf(" %c",&ch);
	if (cnt==EOF)
		tok.tag=EOF;
	else if (ch=='.') {
		ungetc(ch,stdin);
		tok.tag=NUM;
		if (!scanf("%lf",&tok.val)) {
			puts("Invalid operator .!");
			return 1;
		}
	} else if (isdigit(ch)) {
		ungetc(ch,stdin);
		tok.tag=NUM;
		scanf("%lf",&tok.val);
	} else if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^'||ch=='('||ch==')')
		tok.tag=ch;
	else {
		printf("Invalid operator %c!\n",ch);
		return 1;
	}
	return 0;
}

const pair<char,int> ACC={'a',0};
const int LE_OF_PROD[]={-1,0,0,0,1,1,1,2,2,2,3,3,4,4,};
const int NRIGHT[]={1,3,3,1,3,3,1,2,2,1,3,1,3,1,};

const unordered_map<int,pair<char,int>> ACTION[]={
{{'-',{'s',1}},{'+',{'s',5}},{'(',{'s',6}},{'n',{'s',9}},},
{{'+',{'s',5}},{'-',{'s',1}},{'(',{'s',6}},{'n',{'s',9}},},
{{'*',{'r',6}},{-1,{'r',6}},{'+',{'r',6}},{'-',{'r',6}},{'/',{'r',6}},},
{{-1,ACC},{'+',{'s',11}},{'-',{'s',12}},},
{{'*',{'s',13}},{-1,{'r',3}},{'+',{'r',3}},{'-',{'r',3}},{'/',{'s',14}},},
{{'+',{'s',5}},{'-',{'s',1}},{'(',{'s',6}},{'n',{'s',9}},},
{{'-',{'s',16}},{'+',{'s',20}},{'(',{'s',21}},{'n',{'s',24}},},
{{'*',{'r',9}},{-1,{'r',9}},{'+',{'r',9}},{'-',{'r',9}},{'/',{'r',9}},},
{{'*',{'r',11}},{-1,{'r',11}},{'+',{'r',11}},{'-',{'r',11}},{'/',{'r',11}},{'^',{'s',25}},},
{{'*',{'r',13}},{-1,{'r',13}},{'+',{'r',13}},{'-',{'r',13}},{'/',{'r',13}},{'^',{'r',13}},},
{{'*',{'r',8}},{-1,{'r',8}},{'+',{'r',8}},{'-',{'r',8}},{'/',{'r',8}},},
{{'-',{'s',1}},{'+',{'s',5}},{'(',{'s',6}},{'n',{'s',9}},},
{{'-',{'s',1}},{'+',{'s',5}},{'(',{'s',6}},{'n',{'s',9}},},
{{'-',{'s',1}},{'+',{'s',5}},{'(',{'s',6}},{'n',{'s',9}},},
{{'-',{'s',1}},{'+',{'s',5}},{'(',{'s',6}},{'n',{'s',9}},},
{{'*',{'r',7}},{-1,{'r',7}},{'+',{'r',7}},{'-',{'r',7}},{'/',{'r',7}},},
{{'+',{'s',20}},{'-',{'s',16}},{'(',{'s',21}},{'n',{'s',24}},},
{{')',{'r',6}},{'*',{'r',6}},{'+',{'r',6}},{'-',{'r',6}},{'/',{'r',6}},},
{{'+',{'s',31}},{'-',{'s',32}},{')',{'s',33}},},
{{')',{'r',3}},{'+',{'r',3}},{'-',{'r',3}},{'*',{'s',34}},{'/',{'s',35}},},
{{'+',{'s',20}},{'-',{'s',16}},{'(',{'s',21}},{'n',{'s',24}},},
{{'-',{'s',16}},{'+',{'s',20}},{'(',{'s',21}},{'n',{'s',24}},},
{{')',{'r',9}},{'*',{'r',9}},{'+',{'r',9}},{'-',{'r',9}},{'/',{'r',9}},},
{{')',{'r',11}},{'*',{'r',11}},{'+',{'r',11}},{'-',{'r',11}},{'/',{'r',11}},{'^',{'s',38}},},
{{')',{'r',13}},{'*',{'r',13}},{'+',{'r',13}},{'-',{'r',13}},{'/',{'r',13}},{'^',{'r',13}},},
{{'n',{'s',9}},{'(',{'s',6}},},
{{'*',{'s',13}},{-1,{'r',1}},{'+',{'r',1}},{'-',{'r',1}},{'/',{'s',14}},},
{{'*',{'s',13}},{-1,{'r',2}},{'+',{'r',2}},{'-',{'r',2}},{'/',{'s',14}},},
{{'*',{'r',4}},{-1,{'r',4}},{'+',{'r',4}},{'-',{'r',4}},{'/',{'r',4}},},
{{'*',{'r',5}},{-1,{'r',5}},{'+',{'r',5}},{'-',{'r',5}},{'/',{'r',5}},},
{{')',{'r',8}},{'*',{'r',8}},{'+',{'r',8}},{'-',{'r',8}},{'/',{'r',8}},},
{{'-',{'s',16}},{'+',{'s',20}},{'(',{'s',21}},{'n',{'s',24}},},
{{'-',{'s',16}},{'+',{'s',20}},{'(',{'s',21}},{'n',{'s',24}},},
{{'*',{'r',12}},{-1,{'r',12}},{'+',{'r',12}},{'-',{'r',12}},{'/',{'r',12}},{'^',{'r',12}},},
{{'-',{'s',16}},{'+',{'s',20}},{'(',{'s',21}},{'n',{'s',24}},},
{{'-',{'s',16}},{'+',{'s',20}},{'(',{'s',21}},{'n',{'s',24}},},
{{')',{'r',7}},{'*',{'r',7}},{'+',{'r',7}},{'-',{'r',7}},{'/',{'r',7}},},
{{'+',{'s',31}},{'-',{'s',32}},{')',{'s',44}},},
{{'n',{'s',24}},{'(',{'s',21}},},
{{'*',{'r',10}},{-1,{'r',10}},{'+',{'r',10}},{'-',{'r',10}},{'/',{'r',10}},},
{{')',{'r',1}},{'+',{'r',1}},{'-',{'r',1}},{'*',{'s',34}},{'/',{'s',35}},},
{{')',{'r',2}},{'+',{'r',2}},{'-',{'r',2}},{'*',{'s',34}},{'/',{'s',35}},},
{{')',{'r',4}},{'*',{'r',4}},{'+',{'r',4}},{'-',{'r',4}},{'/',{'r',4}},},
{{')',{'r',5}},{'*',{'r',5}},{'+',{'r',5}},{'-',{'r',5}},{'/',{'r',5}},},
{{')',{'r',12}},{'*',{'r',12}},{'+',{'r',12}},{'-',{'r',12}},{'/',{'r',12}},{'^',{'r',12}},},
{{')',{'r',10}},{'*',{'r',10}},{'+',{'r',10}},{'-',{'r',10}},{'/',{'r',10}},},
};

const unordered_map<int,int> GOTO[]={
{{0,3},{2,2},{1,4},{3,7},{4,8},},
{{2,10},{3,7},{4,8},},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
{{2,15},{3,7},{4,8},},
{{0,18},{2,17},{1,19},{3,22},{4,23},},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
{{1,26},{2,2},{3,7},{4,8},},
{{1,27},{2,2},{3,7},{4,8},},
{{2,28},{3,7},{4,8},},
{{2,29},{3,7},{4,8},},
unordered_map<int,int>{},
{{2,30},{3,22},{4,23},},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
{{2,36},{3,22},{4,23},},
{{0,37},{2,17},{1,19},{3,22},{4,23},},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
{{4,8},{3,39},},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
{{1,40},{2,17},{3,22},{4,23},},
{{1,41},{2,17},{3,22},{4,23},},
unordered_map<int,int>{},
{{2,42},{3,22},{4,23},},
{{2,43},{3,22},{4,23},},
unordered_map<int,int>{},
unordered_map<int,int>{},
{{4,23},{3,45},},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
unordered_map<int,int>{},
};

int main(void) {
	Token a;
	vector<pair<int,double>> st;
	st.emplace_back(0,0.0);
	int ret=scan(a);
	while (ret==0) {
		int s=st.back().first;
		try {
			pair<char,int> x=ACTION[s].at(a.tag);
			for (int i=0;i<st.size();++i)
				printf("%d ",st[i].first);
			printf("| ");
			
			if (x.first=='s') {
				printf("移入 单词：");
				if (a.tag==EOF)
					puts("<结束>");
				else
					printf("%c\n",a.tag);
				st.emplace_back(x.second,a.val);
				ret=scan(a);
				
			} else if (x.first=='r') {
				printf("根据 %d 归约\n",x.second);
				double val;
				if (x.second==1)
					val=st.end()[-3].second+st.back().second;
				else if (x.second==2)
					val=st.end()[-3].second-st.back().second;
				else if (x.second==3)
					val=st.back().second;
				else if (x.second==4)
					val=st.end()[-3].second*st.back().second;
				else if (x.second==5)
					val=st.end()[-3].second/st.back().second;
				else if (x.second==6)
					val=st.back().second;
				else if (x.second==7)
					val=st.back().second;
				else if (x.second==8)
					val=-st.back().second;
				else if (x.second==9)
					val=st.back().second;
				else if (x.second==10)
					val=pow(st.end()[-3].second,st.back().second);
				else if (x.second==11)
					val=st.back().second;
				else if (x.second==12)
					val=st.end()[-2].second;
				else if (x.second==13)
					val=st.back().second;

				for (int i=0;i<NRIGHT[x.second];i++)
					st.pop_back();
				st.emplace_back(GOTO[st.back().first].at(LE_OF_PROD[x.second]),val);
				
			} else if (x==ACC) {
				puts("接受!");
				printf("%g\n",st.back().second);
				break;
			}
		}
		catch (const out_of_range& ex) {
			puts("Syntax Error!");
			break;
		}
	}
	return 0;
}
